package emulator.GUI.tape;

import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Observable;
import java.util.Observer;

import javax.swing.AbstractButton;
import javax.swing.GroupLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;

import emulator.hardware.io.peripherals.VicTape;

@SuppressWarnings("serial")
public class VicTapePanel extends JPanel implements ActionListener {

	private final static int STATE_IDLE = 0;
	private final static int STATE_PLAY = 1;
	private final static int STATE_RECORD = 2;
	
	private int state = STATE_IDLE;
	private boolean motor_on = false;
	
	private JButton button_record;
	private JButton button_play;
	private JButton button_rewind;
	private JButton button_forward;
	private JButton button_stop;
	private JButton button_eject;
	
	private JLabel motor_led;
	private JLabel save_led;
	
	private JTextField display;
	private JTextField counter;
	
	private VicTape tape;

	public VicTapePanel(VicTape tape)
	{
		this.tape = tape;
		
		initPanel();
		updateState();
		
		tape.addMotorObserver(new MotorStateObserver());
	}

	private void updateState() {
		button_record.setEnabled(state == STATE_IDLE);
		button_play.setEnabled(state == STATE_IDLE);
		button_rewind.setEnabled(state == STATE_IDLE);
		button_forward.setEnabled(state == STATE_IDLE);
		button_stop.setEnabled(state != STATE_IDLE);
		button_eject.setEnabled(state == STATE_IDLE);
		save_led.setIcon(new ImageIcon(state == STATE_RECORD ? "images/red-on-16.png" : "images/red-off-16.png"));
		motor_led.setIcon(new ImageIcon(motor_on ? "images/green-on-16.png" : "images/green-off-16.png"));
		display.setText("Track "+(tape.getCurrentTrack()+1)+"/"+tape.getTrackCount()+" - "+tape.getCurrentLength());
		
		tape.setSwitch(state == STATE_IDLE, state == STATE_RECORD);
	}

	private void initPanel() {
	    button_record = createButton("Record", "images/Play24.gif", "record");
	    button_play = createButton("Play", "images/Play24.gif", "play");
	    button_rewind = createButton("Rewind", "images/Rewind24.gif", "rewind");
	    button_forward = createButton("Forward", "images/FastForward24.gif", "forward");
	    button_stop = createButton("Stop", "images/Stop24.gif", "stop");
	    button_eject = createButton("Eject", "images/Eject24.gif", "eject");

	    save_led = new JLabel(new ImageIcon("images/red-off-16.png"));
	    motor_led = new JLabel(new ImageIcon("images/green-off-16.png"));
	    
		display = new JTextField("Display");
		counter = new JTextField("0000");
		counter.setFont(new Font(display.getFont().getName(),
								 display.getFont().getStyle(),
								 display.getFont().getSize()*2));
		
		JLabel label_save = new JLabel("Save");
		JLabel label_motor = new JLabel("Motor");

		GroupLayout layout = new GroupLayout(this);
		setLayout(layout);
		
		layout.setAutoCreateGaps(true);
		layout.setAutoCreateContainerGaps(true);
		
	    layout.setHorizontalGroup(
	 	       layout.createSequentialGroup()
	 	       		.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
	 	       			.addComponent(display)
	 	       			.addGroup(layout.createSequentialGroup()
			 	       		.addComponent(button_record)
			 	       		.addComponent(button_play)
			 	       		.addComponent(button_rewind)
			 	       		.addComponent(button_forward)
			 	       		.addComponent(button_stop)
			 	       		.addComponent(button_eject)
			 	       	)
	 	       		)
	 	       		.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
	 	       				.addGroup(layout.createSequentialGroup()
	 	       						.addComponent(counter)
	 	       				)
	 	       				.addGroup(layout.createSequentialGroup()
	 	       						.addComponent(save_led)
	 	       						.addComponent(label_save)
	 	       				)
	 	       				.addGroup(layout.createSequentialGroup()
	 	       						.addComponent(motor_led)
	 	       						.addComponent(label_motor)
	 	       				)
	 	       		)
	    );
	    layout.setVerticalGroup(
	 	       layout.createSequentialGroup()
	 	       		.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
	 	       			.addGroup(layout.createSequentialGroup()
		 	       			.addComponent(display)
			 	          	.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
			 		 	       		.addComponent(button_record)
			 		 	       		.addComponent(button_play)
			 		 	       		.addComponent(button_rewind)
			 		 	       		.addComponent(button_forward)
			 		 	       		.addComponent(button_stop)
			 		 	       		.addComponent(button_eject)
			     	         )
	     	             )
		     	        .addGroup(layout.createSequentialGroup()
		     	        		.addComponent(counter)
		     	        		.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
		     	        				.addComponent(save_led)
		     	        				.addComponent(label_save)
		 	       				)
		     	        		.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
		     	        				.addComponent(motor_led)
		     	        				.addComponent(label_motor)
		 	       				)
 	        	         )
    	             )
	    );
	    layout.linkSize(SwingConstants.HORIZONTAL, button_record, button_play);
	    layout.linkSize(SwingConstants.HORIZONTAL, button_record, button_rewind);
	    layout.linkSize(SwingConstants.HORIZONTAL, button_record, button_forward);
	    layout.linkSize(SwingConstants.HORIZONTAL, button_record, button_stop);
	    layout.linkSize(SwingConstants.HORIZONTAL, button_record, button_eject);
	}

	private JButton createButton(String button_text, String button_icon, String button_action)
	{
		JButton button = new JButton(button_text, new ImageIcon(button_icon));
	    button.setVerticalTextPosition(AbstractButton.BOTTOM);
	    button.setHorizontalTextPosition(AbstractButton.CENTER);
	    button.setActionCommand(button_action);
	    button.addActionListener(this);
		return button;
	}

	@Override
	public void actionPerformed(ActionEvent event) {
		if (event.getActionCommand().equals("record"))
		{
			state = STATE_RECORD;
			updateState();
		}
		else if (event.getActionCommand().equals("play"))
		{
			state = STATE_PLAY;
			updateState();
		}
		else if (event.getActionCommand().equals("stop"))
		{
			state = STATE_IDLE;
			updateState();
		}
		else if (event.getActionCommand().equals("rewind"))
		{
			tape.rewind();
			updateState();
		}
		else if (event.getActionCommand().equals("forward"))
		{
			tape.forward();
			updateState();
		}
	}
	
	class MotorStateObserver implements Observer {
		class MotorStateEvent implements Runnable
		{
			private boolean motor_state;
			
			public MotorStateEvent(boolean motor_state)
			{
				this.motor_state = motor_state;
			}
			
			@Override
			public void run() {
				motor_on = !motor_state;
				updateState();
			}
		}
		
		@Override
		public void update(Observable state, Object motor_state) {
		    javax.swing.SwingUtilities.invokeLater(new MotorStateEvent((Boolean)motor_state));
		}
	}
}
